package com.ruibang.glass.material.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruibang.glass.material.constant.Constants;
import com.ruibang.glass.material.constant.MaterialStatusCode;
import com.ruibang.glass.material.constant.MaterialWareHouseCode;
import com.ruibang.glass.material.constant.MaterialWareHouseInTableNameCode;
import com.ruibang.glass.material.domain.req.MaterialBalanceReq;
import com.ruibang.glass.material.dto.MaterialBalanceDTO;
import com.ruibang.glass.material.entity.MaterialALLInventoryManagement;
import com.ruibang.glass.material.mapper.GMaterialALLInventoryManagementMapper;
import com.ruibang.glass.material.service.MaterialBalanceService;
import com.teaming.cloud.framework2.common.date.DateUtils;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 结存报表
 * </p>
 *
 * @author mameng
 * @since 2024-03-30
 */
@Service
public class MaterialBalanceServiceImpl implements MaterialBalanceService {

    @Autowired
    private GMaterialALLInventoryManagementMapper materialALLInventoryManagementMapper;

    @Override
    public Page<MaterialBalanceDTO> getMaterialBalanceDTOPage(MaterialBalanceReq materialBalanceReq) {
        if (StringUtils.isBlank(materialBalanceReq.getWarehouseCode())) {
            throw new ServiceException(MaterialStatusCode.SEARCH_FAIL_NO_CODE.getCode(), MaterialStatusCode.SEARCH_FAIL_NO_CODE.getMsg());
        }
        if (materialBalanceReq.getSearchDate() == null) {
            throw new ServiceException(MaterialStatusCode.BALANCE_NO_DATE.getCode(), MaterialStatusCode.BALANCE_NO_DATE.getMsg());
        }
        if (StringUtils.isNotEmpty(materialBalanceReq.getSearchDate())) {
            DateTime dateTime = DateUtil.parse(materialBalanceReq.getSearchDate(), "yyyy-MM");
            materialBalanceReq.setSearchNewDate(dateTime);
        }

        for (MaterialWareHouseInTableNameCode ele : MaterialWareHouseInTableNameCode.values()) {
            //更具模块查询不同模块物料的基础信息
            if (materialBalanceReq.getWarehouseCode().equals(ele.getCode())) {
                //获取对应表名
                String tableName = ele.getMsg();
                Page<MaterialBalanceDTO> page = materialALLInventoryManagementMapper.pageMaterialBalanceDTO(new Page<MaterialBalanceDTO>(materialBalanceReq.getPageNo(), materialBalanceReq.getPageSize())
                        , materialBalanceReq);
                //按照物料名称和code 查询对应表 本月的出入库数据
                if (CollectionUtils.isNotEmpty(page.getRecords())) {
                    for (MaterialBalanceDTO materialBalanceDTO : page.getRecords()) {
                        BigDecimal avgPrice = BigDecimal.ZERO;
                        MaterialBalanceDTO materialBalanceDTOIn = materialALLInventoryManagementMapper.getMaterialBalanceDTOIn(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode()
                                , materialBalanceReq.getWarehouseCode(), materialBalanceReq.getSearchNewDate(), tableName);
                        if (materialBalanceDTOIn != null) {
                            if (materialBalanceDTOIn.getByInPrice() != null && materialBalanceDTOIn.getByInQuantity() != null) {
                                materialBalanceDTO.setByInPrice(materialBalanceDTOIn.getByInPrice());
                                materialBalanceDTO.setByInQuantity(materialBalanceDTOIn.getByInQuantity());
                                BigDecimal inAllPrice = materialBalanceDTOIn.getByInPrice().multiply(materialBalanceDTOIn.getByInQuantity()).setScale(6, RoundingMode.HALF_UP);
                                materialBalanceDTO.setByInAllPrice(inAllPrice);
                                avgPrice = materialBalanceDTO.getCqPrice();
                            }
                        } else {
                            materialBalanceDTO.setByInPrice(BigDecimal.ZERO);
                            materialBalanceDTO.setByInQuantity(BigDecimal.ZERO);
                            materialBalanceDTO.setByInAllPrice(BigDecimal.ZERO);
                        }
                        //计算出库总量和金额
                        MaterialBalanceDTO materialBalanceDTOOut = materialALLInventoryManagementMapper.getMaterialBalanceDTOOut(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode()
                                , materialBalanceReq.getWarehouseCode(), materialBalanceReq.getSearchNewDate());

                        if (materialBalanceDTOOut != null) {
                            materialBalanceDTO.setByOutQuantity(materialBalanceDTOOut.getByOutQuantity());
                            if (materialBalanceDTOOut.getByOutQuantity() != null) {
                                if (materialBalanceDTOIn != null) {
                                    if (materialBalanceDTOIn.getByInPrice() != null) {
                                        materialBalanceDTO.setByOutPrice(materialBalanceDTOIn.getByInPrice());
                                        BigDecimal outAllPrice = materialBalanceDTOIn.getByInPrice().multiply(materialBalanceDTOOut.getByOutQuantity()).setScale(6, RoundingMode.HALF_UP);
                                        materialBalanceDTO.setByOutAllPrice(outAllPrice);
                                    }
                                }
                            } else {
                                materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                                materialBalanceDTO.setByOutAllPrice(BigDecimal.ZERO);
                            }
                        } else {
                            materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                            materialBalanceDTO.setByOutAllPrice(BigDecimal.ZERO);
                            materialBalanceDTO.setByOutQuantity(BigDecimal.ZERO);
                        }
                        //计算期初 判断上个月数据库是否有次物品
                        //获取上月日期
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(materialBalanceReq.getSearchNewDate());
                        // 设置日期为上个月的今天
                        calendar.add(Calendar.MONTH, -1);
                        // 获取上个月的日期
                        Date lastMonthDate = calendar.getTime();
                        Long aLong = materialALLInventoryManagementMapper.selectCount(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                                .le(MaterialALLInventoryManagement::getCreateTime, lastMonthDate).eq(MaterialALLInventoryManagement::getWareHouseCode, materialBalanceReq.getWarehouseCode())
                                .eq(MaterialALLInventoryManagement::getMaterialName, materialBalanceDTO.getItemName()));
                        //期初为0
                        if (aLong == 0L) {
                            materialBalanceDTO.setCqPrice(BigDecimal.ZERO);
                            materialBalanceDTO.setCqQuantity(BigDecimal.ZERO);
                            materialBalanceDTO.setCqStayPrice(BigDecimal.ZERO);
                        }
                        //期末
                        Long aLong1 = materialALLInventoryManagementMapper.selectCount(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                                .le(MaterialALLInventoryManagement::getCreateTime, materialBalanceReq.getSearchNewDate()).eq(MaterialALLInventoryManagement::getWareHouseCode, materialBalanceReq.getWarehouseCode())
                                .eq(MaterialALLInventoryManagement::getMaterialName, materialBalanceDTO.getItemName()));
                        if (aLong1 == 0L) {
                            materialBalanceDTO.setQmPrice(BigDecimal.ZERO);
                            materialBalanceDTO.setQmQuantity(BigDecimal.ZERO);
                            materialBalanceDTO.setQmStayPrice(BigDecimal.ZERO);
                        } else {
                            MaterialBalanceDTO materialBalanceDTOQm = materialALLInventoryManagementMapper.getMaterialBalanceDTOQm(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode(), materialBalanceReq.getWarehouseCode());
                            materialBalanceDTO.setCqPrice(avgPrice);
                            materialBalanceDTO.setCqQuantity(materialBalanceDTOQm.getQmQuantity());
                            materialBalanceDTO.setQmPrice(avgPrice);
                            materialBalanceDTO.setQmQuantity(materialBalanceDTOQm.getQmQuantity());
                            if (materialBalanceDTOQm.getQmQuantity() != null) {
                                materialBalanceDTO.setQmStayPrice(materialBalanceDTOQm.getQmQuantity().multiply(avgPrice));
                                materialBalanceDTO.setCqStayPrice(materialBalanceDTOQm.getQmQuantity().multiply(avgPrice));
                            }
                        }
                    }
                }
                return page;
            }
        }

        return null;
    }

    @Override
    public Page<MaterialBalanceDTO> getBCPMaterialBalanceDTOPage(MaterialBalanceReq materialBalanceReq) {
        materialBalanceReq.setWarehouseCode(MaterialWareHouseCode.BCPK_CK.getMsg());
        Page<MaterialBalanceDTO> page = materialALLInventoryManagementMapper.pageMaterialBCPBalanceDTO(new Page<MaterialBalanceDTO>(materialBalanceReq.getPageNo(), materialBalanceReq.getPageSize())
                , materialBalanceReq);
        if (StringUtils.isNotEmpty(materialBalanceReq.getSearchDate())) {
            DateTime dateTime = DateUtil.parse(materialBalanceReq.getSearchDate(), "yyyy-MM");
            materialBalanceReq.setSearchNewDate(dateTime);
        }
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            for (MaterialBalanceDTO materialBalanceDTO : page.getRecords()) {

                MaterialBalanceDTO cpOther = materialALLInventoryManagementMapper.getCpOther(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode());
                if (cpOther!=null){
                    materialBalanceDTO.setWarehouseName(cpOther.getWarehouseName());
                    materialBalanceDTO.setSpecification(cpOther.getSpecification());
                    materialBalanceDTO.setUnit(cpOther.getUnit());
                }

                BigDecimal avgPrice = BigDecimal.ZERO;
                MaterialBalanceDTO materialBalanceDTOIn = materialALLInventoryManagementMapper.getMaterialBCPBalanceDTOIn(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode()
                        , materialBalanceReq.getWarehouseCode(), materialBalanceReq.getSearchNewDate());
                if (materialBalanceDTOIn != null) {
                    if (materialBalanceDTOIn.getByInQuantity() != null) {
                        materialBalanceDTO.setByInPrice(BigDecimal.ZERO);
                        materialBalanceDTO.setByInQuantity(materialBalanceDTOIn.getByInQuantity());
                        materialBalanceDTO.setByInAllPrice(BigDecimal.ZERO);
                        avgPrice = materialBalanceDTO.getCqPrice();
                    }
                } else {
                    materialBalanceDTO.setByInPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setByInQuantity(BigDecimal.ZERO);
                    materialBalanceDTO.setByInAllPrice(BigDecimal.ZERO);
                }
                //计算出库总量和金额
                MaterialBalanceDTO materialBalanceDTOOut = materialALLInventoryManagementMapper.getMaterialBCPBalanceDTOOut(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode()
                        , materialBalanceReq.getWarehouseCode(), materialBalanceReq.getSearchNewDate());
                if (materialBalanceDTOOut != null) {
                    if (materialBalanceDTOOut.getByOutQuantity() != null) {
                        materialBalanceDTO.setByOutQuantity(materialBalanceDTOOut.getByOutQuantity());
                        if (materialBalanceDTOOut.getByOutPrice()!=null){
                            materialBalanceDTO.setByOutPrice(materialBalanceDTOOut.getByOutPrice());
                            BigDecimal multiply = materialBalanceDTOOut.getByOutPrice().multiply(materialBalanceDTOOut.getByOutQuantity());
                            materialBalanceDTO.setByOutAllPrice(multiply);
                        }
                    } else {
                        materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                        materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                        materialBalanceDTO.setByOutAllPrice(BigDecimal.ZERO);
                    }
                } else {
                    materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setByOutAllPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setByOutQuantity(BigDecimal.ZERO);
                }
                //计算期初 判断上个月数据库是否有次物品
                //获取上月日期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(materialBalanceReq.getSearchNewDate());
                // 设置日期为上个月的今天
                calendar.add(Calendar.MONTH, -1);
                // 获取上个月的日期
                Date lastMonthDate = calendar.getTime();
                Long aLong = materialALLInventoryManagementMapper.selectCount(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .le(MaterialALLInventoryManagement::getCreateTime, lastMonthDate).eq(MaterialALLInventoryManagement::getWareHouseCode, materialBalanceReq.getWarehouseCode())
                        .eq(MaterialALLInventoryManagement::getMaterialName, materialBalanceDTO.getItemName()));
                //期初为0
                if (aLong == 0L) {
                    materialBalanceDTO.setCqPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setCqQuantity(BigDecimal.ZERO);
                    materialBalanceDTO.setCqStayPrice(BigDecimal.ZERO);
                }
                //期末
                Long aLong1 = materialALLInventoryManagementMapper.selectCount(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .le(MaterialALLInventoryManagement::getCreateTime, materialBalanceReq.getSearchNewDate()).eq(MaterialALLInventoryManagement::getWareHouseCode, materialBalanceReq.getWarehouseCode())
                        .eq(MaterialALLInventoryManagement::getMaterialName, materialBalanceDTO.getItemName()));
                if (aLong1 == 0L) {
                    materialBalanceDTO.setQmPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setQmQuantity(BigDecimal.ZERO);
                    materialBalanceDTO.setQmStayPrice(BigDecimal.ZERO);
                } else {
                    MaterialBalanceDTO materialBalanceDTOQm = materialALLInventoryManagementMapper.getMaterialBCPBalanceDTOQm(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode(), materialBalanceReq.getWarehouseCode());
                    materialBalanceDTO.setCqPrice(avgPrice);
                    materialBalanceDTO.setCqQuantity(materialBalanceDTOQm.getQmQuantity());
                    materialBalanceDTO.setQmPrice(avgPrice);
                    materialBalanceDTO.setQmQuantity(materialBalanceDTOQm.getQmQuantity());
                    if (materialBalanceDTOQm.getQmQuantity() != null) {
                        materialBalanceDTO.setQmStayPrice(materialBalanceDTOQm.getQmQuantity().multiply(avgPrice));
                        materialBalanceDTO.setCqStayPrice(materialBalanceDTOQm.getQmQuantity().multiply(avgPrice));
                    }
                }
            }
        }
        return page;
    }

    @Override
    public Page<MaterialBalanceDTO> getCPMaterialBalanceDTOPage(MaterialBalanceReq materialBalanceReq) {
        materialBalanceReq.setWarehouseCode(MaterialWareHouseCode.CPK_CK.getMsg());
        Page<MaterialBalanceDTO> page = materialALLInventoryManagementMapper.pageMaterialCPBalanceDTO(new Page<MaterialBalanceDTO>(materialBalanceReq.getPageNo(), materialBalanceReq.getPageSize())
                , materialBalanceReq);

        if (StringUtils.isNotEmpty(materialBalanceReq.getSearchDate())) {
            DateTime dateTime = DateUtil.parse(materialBalanceReq.getSearchDate(), "yyyy-MM");
            materialBalanceReq.setSearchNewDate(dateTime);
        }
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            for (MaterialBalanceDTO materialBalanceDTO : page.getRecords()) {
                MaterialBalanceDTO cpOther = materialALLInventoryManagementMapper.getCpOther(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode());
                if (cpOther!=null){
                    materialBalanceDTO.setWarehouseName(cpOther.getWarehouseName());
                    materialBalanceDTO.setSpecification(cpOther.getSpecification());
                    materialBalanceDTO.setUnit(cpOther.getUnit());
                }


                BigDecimal avgPrice = BigDecimal.ZERO;
                MaterialBalanceDTO materialBalanceDTOIn = materialALLInventoryManagementMapper.getMaterialCPBalanceDTOIn(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode()
                        , materialBalanceReq.getWarehouseCode(), materialBalanceReq.getSearchNewDate());
                if (materialBalanceDTOIn != null) {
                    if (materialBalanceDTOIn.getByInQuantity() != null) {
                        materialBalanceDTO.setByInPrice(BigDecimal.ZERO);
                        materialBalanceDTO.setByInQuantity(materialBalanceDTOIn.getByInQuantity());
                        materialBalanceDTO.setByInAllPrice(BigDecimal.ZERO);
                        avgPrice = materialBalanceDTO.getCqPrice();
                    }
                } else {
                    materialBalanceDTO.setByInPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setByInQuantity(BigDecimal.ZERO);
                    materialBalanceDTO.setByInAllPrice(BigDecimal.ZERO);
                }

                //计算出库总量和金额
                MaterialBalanceDTO materialBalanceDTOOut = materialALLInventoryManagementMapper.getMaterialCPBalanceDTOOut(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode()
                        , materialBalanceReq.getWarehouseCode(), materialBalanceReq.getSearchNewDate());
                if (materialBalanceDTOOut != null) {
                    if (materialBalanceDTOOut.getByOutQuantity() != null) {
                        materialBalanceDTO.setByOutQuantity(materialBalanceDTOOut.getByOutQuantity());
                        if (materialBalanceDTOOut.getByOutPrice()!=null){
                            materialBalanceDTO.setByOutPrice(materialBalanceDTOOut.getByOutPrice());
                            BigDecimal multiply = materialBalanceDTOOut.getByOutPrice().multiply(materialBalanceDTOOut.getByOutQuantity());
                            materialBalanceDTO.setByOutAllPrice(multiply);
                        }
                    } else {
                        materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                        materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                        materialBalanceDTO.setByOutAllPrice(BigDecimal.ZERO);
                    }
                } else {
                    materialBalanceDTO.setByOutPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setByOutAllPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setByOutQuantity(BigDecimal.ZERO);
                }

                //计算期初 判断上个月数据库是否有次物品
                //获取上月日期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(materialBalanceReq.getSearchNewDate());
                // 设置日期为上个月的今天
                calendar.add(Calendar.MONTH, -1);
                // 获取上个月的日期
                Date lastMonthDate = calendar.getTime();
                Long aLong = materialALLInventoryManagementMapper.selectCount(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .le(MaterialALLInventoryManagement::getCreateTime, lastMonthDate).eq(MaterialALLInventoryManagement::getWareHouseCode, materialBalanceReq.getWarehouseCode())
                        .eq(MaterialALLInventoryManagement::getMaterialName, materialBalanceDTO.getItemName()));
                //期初为0
                if (aLong == 0L) {
                    materialBalanceDTO.setCqPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setCqQuantity(BigDecimal.ZERO);
                    materialBalanceDTO.setCqStayPrice(BigDecimal.ZERO);
                }
                //期末
                Long aLong1 = materialALLInventoryManagementMapper.selectCount(Wrappers.<MaterialALLInventoryManagement>lambdaQuery()
                        .le(MaterialALLInventoryManagement::getCreateTime, materialBalanceReq.getSearchNewDate()).eq(MaterialALLInventoryManagement::getWareHouseCode, materialBalanceReq.getWarehouseCode())
                        .eq(MaterialALLInventoryManagement::getMaterialName, materialBalanceDTO.getItemName()));
                if (aLong1 == 0L) {
                    materialBalanceDTO.setQmPrice(BigDecimal.ZERO);
                    materialBalanceDTO.setQmQuantity(BigDecimal.ZERO);
                    materialBalanceDTO.setQmStayPrice(BigDecimal.ZERO);
                } else {
                    MaterialBalanceDTO materialBalanceDTOQm = materialALLInventoryManagementMapper.getMaterialCPBalanceDTOQm(materialBalanceDTO.getItemName(), materialBalanceDTO.getItemCode(), materialBalanceReq.getWarehouseCode());
                    materialBalanceDTO.setCqPrice(avgPrice);
                    materialBalanceDTO.setCqQuantity(materialBalanceDTOQm.getQmQuantity());
                    materialBalanceDTO.setQmPrice(avgPrice);
                    materialBalanceDTO.setQmQuantity(materialBalanceDTOQm.getQmQuantity());
                    if (materialBalanceDTOQm.getQmQuantity() != null) {
                        materialBalanceDTO.setQmStayPrice(materialBalanceDTOQm.getQmQuantity().multiply(avgPrice));
                        materialBalanceDTO.setCqStayPrice(materialBalanceDTOQm.getQmQuantity().multiply(avgPrice));
                    }
                }
            }
        }
        return page;
    }
}
